bitkeeper revision 1.1629.1.1 (429de4faESWSriZYlaDxRVk7hKj32g)
authorcl349@firebug.cl.cam.ac.uk <cl349@firebug.cl.cam.ac.uk>
Wed, 1 Jun 2005 16:40:26 +0000 (16:40 +0000)
committercl349@firebug.cl.cam.ac.uk <cl349@firebug.cl.cam.ac.uk>
Wed, 1 Jun 2005 16:40:26 +0000 (16:40 +0000)
All page directory pages have to be pinned before/during relocation, so
that the entries they contain can be canonicalised during relocation.
mmu_context.h, mmu.h, pgtable.c, ldt.c, reboot.c:
  Pin all unpinned in-use pgd's before relocation.
reboot.c:
  Flush the pgd cache before relocation.
Signed-off-by: Christian Limpach <Christian.Limpach@cl.cam.ac.uk>
linux-2.6.11-xen-sparse/arch/xen/i386/kernel/ldt.c
linux-2.6.11-xen-sparse/arch/xen/i386/mm/pgtable.c
linux-2.6.11-xen-sparse/arch/xen/kernel/reboot.c
linux-2.6.11-xen-sparse/include/asm-xen/asm-i386/mmu.h
linux-2.6.11-xen-sparse/include/asm-xen/asm-i386/mmu_context.h

index cee69b73edb1f4214cb9bfd3a5db67fd34c91017..675509e0bee40c968bdb0abc1c7ed501986efe4f 100644 (file)
@@ -18,6 +18,7 @@
 #include <asm/system.h>
 #include <asm/ldt.h>
 #include <asm/desc.h>
+#include <asm/mmu_context.h>
 
 #ifdef CONFIG_SMP /* avoids "defined but not used" warnig */
 static void flush_ldt(void *null)
@@ -108,6 +109,11 @@ int init_new_context(struct task_struct *tsk, struct mm_struct *mm)
                retval = copy_ldt(&mm->context, &old_mm->context);
                up(&old_mm->context.sem);
        }
+       if (retval == 0) {
+               spin_lock(&mm_unpinned_lock);
+               list_add(&mm->context.unpinned, &mm_unpinned);
+               spin_unlock(&mm_unpinned_lock);
+       }
        return retval;
 }
 
@@ -128,6 +134,9 @@ void destroy_context(struct mm_struct *mm)
                        kfree(mm->context.ldt);
                mm->context.size = 0;
        }
+       spin_lock(&mm_unpinned_lock);
+       list_del(&mm->context.unpinned);
+       spin_unlock(&mm_unpinned_lock);
 }
 
 static int read_ldt(void __user * ptr, unsigned long bytecount)
index 0215422a5aa98641cbee8fe14071324ff783cf77..f3756654c31a12f6057898490490bc8e9e93ec52 100644 (file)
@@ -408,6 +408,9 @@ void make_pages_writable(void *va, unsigned int nr)
 }
 #endif /* CONFIG_XEN_SHADOW_MODE */
 
+LIST_HEAD(mm_unpinned);
+DEFINE_SPINLOCK(mm_unpinned_lock);
+
 static inline void mm_walk_set_prot(void *pt, pgprot_t flags)
 {
        struct page *page = virt_to_page(pt);
@@ -461,6 +464,9 @@ void mm_pin(struct mm_struct *mm)
         pfn_pte(virt_to_phys(mm->pgd)>>PAGE_SHIFT, PAGE_KERNEL_RO), 0);
     xen_pgd_pin(__pa(mm->pgd));
     mm->context.pinned = 1;
+    spin_lock(&mm_unpinned_lock);
+    list_del(&mm->context.unpinned);
+    spin_unlock(&mm_unpinned_lock);
 
     spin_unlock(&mm->page_table_lock);
 }
@@ -475,10 +481,20 @@ void mm_unpin(struct mm_struct *mm)
         pfn_pte(virt_to_phys(mm->pgd)>>PAGE_SHIFT, PAGE_KERNEL), 0);
     mm_walk(mm, PAGE_KERNEL);
     mm->context.pinned = 0;
+    spin_lock(&mm_unpinned_lock);
+    list_add(&mm->context.unpinned, &mm_unpinned);
+    spin_unlock(&mm_unpinned_lock);
 
     spin_unlock(&mm->page_table_lock);
 }
 
+void mm_pin_all(void)
+{
+    while (!list_empty(&mm_unpinned))  
+       mm_pin(list_entry(mm_unpinned.next, struct mm_struct,
+                         context.unpinned));
+}
+
 void _arch_exit_mmap(struct mm_struct *mm)
 {
     struct task_struct *tsk = current;
index 4e6dcf649dceaac915ec6fee0009abbe8f2f56b6..62c827489592c7ce855acf557b8e1c6b03178959 100644 (file)
@@ -103,6 +103,9 @@ static void __do_suspend(void)
 
     __cli();
 
+    mm_pin_all();
+    kmem_cache_shrink(pgd_cache);
+
     netif_suspend();
 
     blkdev_suspend();
index 0e27763469b66d13a3cedb48b36cf1353c94275d..b628b46f3be794476ec2511afecb6c27f5bc1a8b 100644 (file)
@@ -13,8 +13,12 @@ typedef struct {
        struct semaphore sem;
        void *ldt;
        unsigned pinned:1;
+       struct list_head unpinned;
 } mm_context_t;
 
+extern struct list_head mm_unpinned;
+extern spinlock_t mm_unpinned_lock;
+
 /* mm/memory.c:exit_mmap hook */
 extern void _arch_exit_mmap(struct mm_struct *mm);
 #define arch_exit_mmap(_mm) _arch_exit_mmap(_mm)
index b1fe2fb594190f3998d769a4cd43fceb05d60621..f46144e37f1ffc1eac52f69a35c07d2c335d1a08 100644 (file)
@@ -43,6 +43,7 @@ static inline void __prepare_arch_switch(void)
 
 extern void mm_pin(struct mm_struct *mm);
 extern void mm_unpin(struct mm_struct *mm);
+void mm_pin_all(void);
 
 static inline void switch_mm(struct mm_struct *prev,
                             struct mm_struct *next,